package Algorithm.interview;

/**
 * @Author self
 * @Date 2024/10/6 18:13
 * @Describe 题目
 * 给两个单词 word1 和 word2， 请返回将 word1 转换成 word2 所使用的最少操作数 。
 * 你可以对一个单词进行如下三种操作：
 *
 * 插入一个字符
 * 删除一个字符
 * 替换一个字符
 * 示例 1：
 *
 * 输入：word1 = "horse", word2 = "ros"
 * 输出：3
 * 解释：
 * horse -> rorse (将 'h' 替换为 'r')
 * rorse -> rose (删除 'r')
 * rose -> ros (删除 'e')
 * 示例 2：
 *
 * 输入：word1 = "intention", word2 = "execution"
 * 输出：5
 * 解释：
 * intention -> inention (删除 't')
 * inention -> enention (将 'i' 替换为 'e')
 * enention -> exention (将 'n' 替换为 'x')
 * exention -> exection (将 'n' 替换为 'c')
 * exection -> execution (插入 'u')
 * 提示：
 *
 * 0 <= word1.length, word2.length <= 500
 * word1 和 word2 由小写英文字母组成
 *
 * 问题分析
 * 给定两个字符串 word1 和 word2，我们需要找到将 word1 转换为 word2 的最小编辑距离。
 *
 * 动态规划解法
 * 创建一个二维数组 dp，其中 dp[i][j] 表示将 word1 的前 i 个字符转换为 word2 的前 j 个字符的最小编辑距离。
 * 初始化边界条件：
 * dp[i][0] = i：将 word1 的前 i 个字符转换为空字符串需要 i 次删除操作。
 * dp[0][j] = j：将空字符串转换为 word2 的前 j 个字符需要 j 次插入操作。
 * 填充 DP 表：
 * 如果 word1[i-1] == word2[j-1]，则 dp[i][j] = dp[i-1][j-1]（不需要额外操作）。
 * 如果不相等，则取以下三种情况的最小值：
 * 删除操作：dp[i-1][j] + 1
 * 插入操作：dp[i][j-1] + 1
 * 替换操作：dp[i-1][j-1] + 1
 * 最后，dp[word1.length()][word2.length()] 的值就是所需的最小编辑距离。
 */
public class EditDistance {
    public int minDistance(String word1, String word2) {
        int m = word1.length();
        int n = word2.length();

        // 创建 DP 数组
        int[][] dp = new int[m + 1][n + 1];

        // 初始化边界条件
        for (int i = 0; i <= m; i++) {
            dp[i][0] = i;  // word1 的前 i 个字符转换为空字符串
        }
        for (int j = 0; j <= n; j++) {
            dp[0][j] = j;  // 空字符串转换为 word2 的前 j 个字符
        }

        // 填充 DP 表
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1]; // 不需要额外操作
                } else {
                    dp[i][j] = Math.min(Math.min(dp[i - 1][j] + 1,    // 删除
                            dp[i][j - 1] + 1),   // 插入
                            dp[i - 1][j - 1] + 1); // 替换
                }
            }
        }

        return dp[m][n];  // 返回编辑距离
    }

    public static void main(String[] args) {
        EditDistance solution = new EditDistance();
        String word1 = "horse";
        String word2 = "ros";

        String word3 = "intention";
        String word4 = "execution";

        int result = solution.minDistance(word1, word2);
        System.out.println("编辑距离是: " + result);  // 输出结果

        int result2 = solution.minDistance(word3, word4);
        System.out.println("编辑距离是: " + result2);  // 输出结果
    }
}
